<template>
    <div class="message-view">
        <div class="container">
            <el-button @click="backTo" type="primary" plain :icon="ArrowLeft" class="back-btn">
                返回
            </el-button>

            <div class="danmu-wall">
                <!-- 弹幕容器 -->
                <div class="danmu-container" ref="danmuContainerRef" :style="{ backgroundImage: `url(${danmuImg})` }">
                    <div v-for="danmu in currentBatch" :key="danmu.uniqueId"
                        :ref="el => setDanmuRef(el, danmu.uniqueId)" class="danmu-item" :style="{
                            top: `${danmu.top}px`,
                            left: `${danmu.left}px`,
                            backgroundColor: danmu.color || getRandomColor()
                        }">
                        <span class="danmu-text">{{ danmu.content }}</span>
                    </div>
                </div>

                <!-- 输入区域 -->
                <div class="input-area">
                    <div class="input-wrapper">
                        <input v-model="inputText" type="text" class="danmu-input" placeholder="留下点什么啦~"
                            :disabled="!isLoggedIn" @focus="showSendButton = true" @blur="handleInputBlur"
                            @keydown.enter.prevent="handleSend" />
                        <button v-if="showSendButton" class="send-button" :disabled="!canSend" @click="handleSend">
                            发射
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { ArrowLeft } from '@element-plus/icons-vue'
import { addDanmu, getAllDanmus } from '../api/index'
import danmuImg from '../assets/img/danmu-img.png'

const router = useRouter()
const danmuContainerRef = ref<HTMLElement | null>(null)
const inputText = ref('')
const showSendButton = ref(false)
const isLoggedIn = ref(false)
const danmuData = ref<any[]>([]) // 存储所有弹幕数据
const currentBatch = ref<any[]>([]) // 当前正在显示的20条弹幕
const isLoading = ref(false) // 是否正在加载数据
let uniqueIdCounter = 0
let checkInterval: number | null = null
const danmuRefs = new Map<number, HTMLElement>() // 存储弹幕元素的引用
let animationFrameId: number | null = null // requestAnimationFrame ID
let isAnimating = false // 是否正在执行动画

// 检查是否登录
const checkLogin = () => {
    const token = localStorage.getItem('AUTO_TOKEN')
    isLoggedIn.value = !!token
}

// 生成随机颜色（十六进制）
const getRandomColor = () => {
    const colors = [
        '#FF6B6B', '#4ECDC4', '#FFE66D', '#95E1D3', '#F38181',
        '#AA96DA', '#FCBAD3', '#FFD93D', '#6BCB77', '#FF6B9D',
        '#C44569', '#F8B500', '#00D2FF', '#A8E6CF', '#FFD3A5',
        '#FD9853', '#A8D8EA', '#AA96DA', '#FCBAD3', '#FFD93D'
    ]
    return colors[Math.floor(Math.random() * colors.length)]
}

// 判断是否可以发送
const canSend = computed(() => {
    return inputText.value.trim().length > 0 && isLoggedIn.value
})

// 网络请求获取弹幕数据
const fetchDanmus = async () => {
    if (isLoading.value) return

    isLoading.value = true
    try {
        const result = await getAllDanmus()
        if (result.code === 200) {
            const newDanmus = result.data || []
            // 将所有数据存储在数组中
            danmuData.value = [...danmuData.value, ...newDanmus]
        }
    } catch (error) {
        console.error('获取弹幕失败:', error)
    } finally {
        isLoading.value = false
    }
}

// 从数组中随机获取20条不重复的数据
const getRandomDanmus = (count: number = 20): any[] => {
    if (danmuData.value.length === 0) return []

    // 如果数据不足20条，返回所有数据
    if (danmuData.value.length <= count) {
        return [...danmuData.value]
    }

    // 随机选择不重复的数据
    const selected: any[] = []
    const usedIndices = new Set<number>()
    const maxCount = Math.min(count, danmuData.value.length)

    while (selected.length < maxCount) {
        const randomIndex = Math.floor(Math.random() * danmuData.value.length)
        if (!usedIndices.has(randomIndex)) {
            usedIndices.add(randomIndex)
            selected.push(danmuData.value[randomIndex])
        }
    }

    return selected
}

// 渲染下一批弹幕
const renderNextBatch = () => {
    // 如果数据不足20条，先请求数据
    if (danmuData.value.length < 20 && !isLoading.value) {
        fetchDanmus()
    }

    // 如果数据仍然不足，等待数据加载
    if (danmuData.value.length === 0) {
        return
    }

    // 随机获取20条不重复的数据
    const batch = getRandomDanmus(20)

    if (!danmuContainerRef.value) return
    const containerWidth = danmuContainerRef.value.offsetWidth
    const containerHeight = danmuContainerRef.value.offsetHeight

    // 为每条弹幕分配位置和动画参数
    currentBatch.value = batch.map((danmu: any) => {
        // 随机分配垂直位置（0到容器高度-50px，留出一些边距）
        const top = Math.random() * (containerHeight - 50)
        // 随机速度（每秒移动的像素数，范围：100-150px/s）
        const speed = 100 + Math.random() * 50
        // 初始位置在容器右侧外
        const left = containerWidth

        return {
            ...danmu,
            uniqueId: uniqueIdCounter++, // 唯一ID，用于key
            top,
            left,
            speed,
            // 使用数据表中的颜色，如果没有则随机生成
            color: danmu.color || getRandomColor()
        }
    })

    // 开始动画
    startAnimation()
}

// 设置弹幕元素的引用
const setDanmuRef = (el: any, uniqueId: number) => {
    if (el) {
        danmuRefs.set(uniqueId, el)
    } else {
        // 元素被移除时，清理引用
        danmuRefs.delete(uniqueId)
    }
}

// 移除弹幕
const removeDanmu = (uniqueId: number) => {
    // 从数组中删除，Vue 会自动从 DOM 中移除该元素
    const index = currentBatch.value.findIndex(d => d.uniqueId === uniqueId)
    if (index !== -1) {
        currentBatch.value.splice(index, 1)
    }

    // 清理引用
    danmuRefs.delete(uniqueId)

    // 如果当前批次为空，渲染下一批
    if (currentBatch.value.length === 0) {
        // 延迟一点时间，确保屏幕清空
        setTimeout(() => {
            renderNextBatch()
        }, 100)
    }
}

// 开始动画
const startAnimation = () => {
    // 如果已经在动画中，不需要重新启动
    if (isAnimating) return

    // 如果没有弹幕，不启动动画
    if (currentBatch.value.length === 0) return

    isAnimating = true

    let lastTime = performance.now()

    const animate = (currentTime: number) => {
        if (!danmuContainerRef.value) {
            isAnimating = false
            return
        }

        const deltaTime = (currentTime - lastTime) / 1000 // 转换为秒
        lastTime = currentTime

        // 更新每条弹幕的位置
        for (let i = currentBatch.value.length - 1; i >= 0; i--) {
            const danmu = currentBatch.value[i]

            // 更新left值
            danmu.left -= danmu.speed * deltaTime

            // 获取弹幕元素的实际宽度
            const danmuElement = danmuRefs.get(danmu.uniqueId)
            if (danmuElement) {
                const danmuWidth = danmuElement.offsetWidth
                // 当left <= -弹幕自身宽度时，直接移除
                if (danmu.left <= -danmuWidth) {
                    removeDanmu(danmu.uniqueId)
                }
            } else {
                // 如果元素不存在，直接移除
                removeDanmu(danmu.uniqueId)
            }
        }

        // 如果还有弹幕在移动，继续动画
        if (currentBatch.value.length > 0) {
            animationFrameId = requestAnimationFrame(animate)
        } else {
            // 所有弹幕都已移除，停止动画
            isAnimating = false
        }
    }

    animationFrameId = requestAnimationFrame(animate)
}

// 处理输入框失焦
const handleInputBlur = () => {
    // 延迟隐藏按钮，以便点击按钮时不会立即隐藏
    setTimeout(() => {
        if (!inputText.value.trim()) {
            showSendButton.value = false
        }
    }, 200)
}

// 立即创建并显示弹幕（乐观更新）
const createDanmuImmediately = (content: string) => {
    if (!danmuContainerRef.value) return null

    const containerWidth = danmuContainerRef.value.offsetWidth
    const containerHeight = danmuContainerRef.value.offsetHeight
    const randomColor = getRandomColor()
    const top = Math.random() * (containerHeight - 50)
    const speed = 100 + Math.random() * 50
    const left = containerWidth

    const newDanmu = {
        uniqueId: uniqueIdCounter++,
        content: content,
        color: randomColor,
        top: top,
        left: left,
        speed: speed
    }

    // 立即添加到当前批次
    currentBatch.value.push(newDanmu)

    // 如果动画未运行，启动动画
    if (!isAnimating) {
        startAnimation()
    }

    return newDanmu
}

// 发送弹幕
const handleSend = async () => {
    const content = inputText.value.trim()

    if (!content) {
        ElMessage.warning('请输入弹幕内容')
        return
    }

    if (!isLoggedIn.value) {
        ElMessage.warning('请先登录')
        router.push('/login')
        return
    }

    // 立即创建并显示弹幕
    const newDanmu = createDanmuImmediately(content)

    // 清空输入框
    inputText.value = ''
    showSendButton.value = false

    // 异步发送到服务器
    try {
        const randomColor = newDanmu?.color || getRandomColor()
        const result = await addDanmu({
            content: content,
            color: randomColor,
            speed: 5,
            position: Math.random() * 90
        })

        if (result.code === 200) {
            // 发送成功，将弹幕添加到数据数组
            if (result.data) {
                danmuData.value.push(result.data)
            }
        } else {
            // 发送失败，但弹幕已经显示，只提示错误
            ElMessage.error(result.msg || '弹幕发送失败')
        }
    } catch (error: any) {
        console.error('发送弹幕失败:', error)
        // 发送失败，但弹幕已经显示，只提示错误
        if (error.response && error.response.status === 401) {
            ElMessage.warning('请先登录')
            router.push('/login')
        } else {
            ElMessage.error('弹幕发送失败，请稍后重试')
        }
    }
}

const backTo = () => {
    router.back()
}

onMounted(() => {
    checkLogin()
    // 初始加载数据
    fetchDanmus().then(() => {
        // 数据加载完成后，渲染第一批
        renderNextBatch()
    })

    // 定期检查登录状态
    checkInterval = window.setInterval(() => {
        checkLogin()
    }, 1000)
})

onUnmounted(() => {
    if (checkInterval) {
        clearInterval(checkInterval)
    }
    // 停止动画
    if (animationFrameId) {
        cancelAnimationFrame(animationFrameId)
        animationFrameId = null
    }
    isAnimating = false
    // 清理所有引用
    danmuRefs.clear()
})
</script>

<style lang="less" scoped>
@import "../assets/varable.less";

.message-view {
    min-height: calc(100vh - 300px);
    padding: 30px 0;
    position: relative;

    .back-btn {
        margin-bottom: 20px;
    }

    .danmu-wall {
        position: relative;
        width: 100%;
        min-height: 600px;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        border-radius: 16px;
        overflow: hidden;
        box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
        background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"><defs><radialGradient id="grad"><stop offset="0%" stop-color="rgba(255,255,255,0.1)"/><stop offset="100%" stop-color="rgba(255,255,255,0)"/></radialGradient></defs><circle cx="200" cy="200" r="300" fill="url(%23grad)"/><circle cx="800" cy="800" r="400" fill="url(%23grad)"/></svg>');
        background-size: cover;
        background-position: center;
    }

    .danmu-container {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        overflow: hidden;
        pointer-events: none;
        z-index: 1;
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
    }

    .danmu-item {
        position: absolute;
        white-space: nowrap;
        font-size: 16px;
        font-weight: 500;
        padding: 8px 16px;
        border-radius: 20px;
        color: #FFFFFF;
        text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
        pointer-events: auto;
        z-index: 2;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
        opacity: 0.9;
        will-change: left;

        &:hover {
            opacity: 1;
        }

        .danmu-text {
            display: inline-block;
            color: #FFFFFF;
            font-weight: 500;
        }
    }

    .input-area {
        position: absolute;
        bottom: 40px;
        left: 50%;
        transform: translateX(-50%);
        z-index: 10;
        width: 100%;
        max-width: 600px;
        padding: 0 20px;
    }

    .input-wrapper {
        display: flex;
        align-items: center;
        gap: 12px;
        background: rgba(255, 255, 255, 0.95);
        padding: 12px 20px;
        border-radius: 30px;
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
        backdrop-filter: blur(10px);
        border: 1px solid rgba(255, 255, 255, 0.3);
        transition: all 0.3s ease;

        &:focus-within {
            box-shadow: 0 6px 25px rgba(0, 0, 0, 0.2);
            transform: translateY(-2px);
        }
    }

    .danmu-input {
        flex: 1;
        border: none;
        outline: none;
        background: transparent;
        font-size: 16px;
        color: #333;
        padding: 0;

        &::placeholder {
            color: #999;
        }

        &:disabled {
            cursor: not-allowed;
            opacity: 0.6;
        }
    }

    .send-button {
        padding: 8px 24px;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: #FFFFFF;
        border: none;
        border-radius: 20px;
        font-size: 14px;
        font-weight: 500;
        cursor: pointer;
        transition: all 0.3s ease;
        white-space: nowrap;
        box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);

        &:hover:not(:disabled) {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.5);
        }

        &:active:not(:disabled) {
            transform: translateY(0);
            box-shadow: 0 2px 6px rgba(102, 126, 234, 0.4);
        }

        &:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
    }
}


// 暗色主题适配
@media (prefers-color-scheme: dark) {
    .message-view {
        .input-wrapper {
            background: rgba(30, 30, 30, 0.95);
        }

        .danmu-input {
            color: #fff;

            &::placeholder {
                color: #999;
            }
        }
    }
}
</style>
